﻿using Analyze.Provider;

namespace Analyze.Calculator
{
    public class Probability
    {
        /**
        * 先验概率计算
        * <h3>先验概率计算</h3>
        * P(c<sub>j</sub>)=N(C=c<sub>j</sub>)<b>/</b>N <br>
        * 其中，N(C=c<sub>j</sub>)表示类别c<sub>j</sub>中的训练文本数量；
        * N表示训练文本集总数量。
        */

        /**
        * 先验概率
        * @param c 给定的分类
        * @return 给定条件下的先验概率
        */
        public static float CalculatePriorProbability(string c)
        {
            TrainingDataProvider provider = TrainingDataProvider.GetInstance();
            float ret = 0F;
            float Nc = provider.GetTrainingCountOfClassification(c);
            float N = provider.GetTrainngCount();
            ret = Nc / N;
            return ret;
        }

        private const float M = 0F;

        /**
       * 计算类条件概率
       * @param x 给定的文本属性
       * @param c 给定的分类
       * @return 给定条件下的类条件概率
       */
        public static float CalculateClassConditionalProbability(string x, string c)
        {
            TrainingDataProvider provider = TrainingDataProvider.GetInstance();
            float ret = 0F;
            float Nxc = provider.GetCountContainKeyOfClassification(c, x);
            float Nc = provider.GetTrainingCountOfClassification(c);
            float V = provider.BlockCount;
            ret = (Nxc + 1f) / (Nc + M + V); //为了避免出现0这样极端情况，进行加权处理
            return ret;
        }
        
        /**
        * 计算类条件概率
        * @param c 给定的分类
        * @return 给定条件下的类条件概率
        */
        public static float NullConditionalProbability(string c)
        {
            TrainingDataProvider provider = TrainingDataProvider.GetInstance();
            float ret = 0F;
            float Nxc = 0;
            float Nc = provider.GetTrainingCountOfClassification(c);
            float V = provider.BlockCount;
            ret = (Nxc + 1f) / (Nc + M + V); //为了避免出现0这样极端情况，进行加权处理
            return ret;
        }
    }
}